// SPDX-License-Identifier: LGPL-3.0-only

#include <rz_cmd.h>
#include <rz_core.h>
#include "cmd_descs.h"

static int task_enqueue(RzCore *core, const char *cmd, bool transient) {
	if (rz_sandbox_enable (0)) {
		eprintf ("This command is disabled in sandbox mode\n");
		return -1;
	}
	RzCoreTask *task = rz_core_task_new (core, true, cmd, NULL, core);
	if (!task) {
		return -1;
	}
	task->transient = transient;
	rz_core_task_enqueue (&core->tasks, task);
	return 0;
}

static int task_output(RzCore *core, int tid) {
	if (!tid) {
		return -1;
	}
	RzCoreTask *task = rz_core_task_get_incref (&core->tasks, tid);
	if (task) {
		if (task->res) {
			rz_cons_println (task->res);
		}
		rz_core_task_decref (task);
	} else {
		eprintf ("Cannot find task\n");
		return -1;
	}
	return 0;
}

static int task_break(RzCore *core, int tid) {
	if (rz_sandbox_enable (0)) {
		eprintf ("This command is disabled in sandbox mode\n");
		return -1;
	}
	if (tid) {
		return -1;
	}
	rz_core_task_break (&core->tasks, tid);
	return 0;
}

RZ_IPI RzCmdStatus rz_tasks_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode) {
	if (argc == 1) {
		rz_core_task_list (core, mode == RZ_OUTPUT_MODE_STANDARD ? '\0' : 'j');
		return RZ_CMD_STATUS_OK;
	} else if (argc == 2) {
		return rz_cmd_int2status (task_enqueue (core, argv[1], false));
	}
	return RZ_CMD_STATUS_ERROR;
}

RZ_IPI RzCmdStatus rz_tasks_transient_handler(RzCore *core, int argc, const char **argv) {
	return rz_cmd_int2status (task_enqueue (core, argv[1], true));
}

RZ_IPI RzCmdStatus rz_tasks_output_handler(RzCore *core, int argc, const char **argv) {
	int tid = rz_num_math (core->num, argv[1]);
	return rz_cmd_int2status (task_output (core, tid));
}

RZ_IPI RzCmdStatus rz_tasks_break_handler(RzCore *core, int argc, const char **argv) {
	int tid = rz_num_math (core->num, argv[1]);
	return rz_cmd_int2status (task_break (core, tid));
}

RZ_IPI RzCmdStatus rz_tasks_delete_handler(RzCore *core, int argc, const char **argv) {
	if (rz_sandbox_enable (0)) {
		eprintf ("This command is disabled in sandbox mode\n");
		return RZ_CMD_STATUS_ERROR;
	}
	int tid = rz_num_math (core->num, argv[1]);
	return rz_core_task_del (&core->tasks, tid)? RZ_CMD_STATUS_OK: RZ_CMD_STATUS_ERROR;
}

RZ_IPI RzCmdStatus rz_tasks_delete_all_handler(RzCore *core, int argc, const char **argv) {
	if (rz_sandbox_enable (0)) {
		eprintf ("This command is disabled in sandbox mode\n");
		return RZ_CMD_STATUS_ERROR;
	}
	rz_core_task_del_all_done (&core->tasks);
	return RZ_CMD_STATUS_OK;
}

RZ_IPI RzCmdStatus rz_tasks_wait_handler(RzCore *core, int argc, const char **argv) {
	if (rz_sandbox_enable (0)) {
		eprintf ("This command is disabled in sandbox mode\n");
		return RZ_CMD_STATUS_ERROR;
	}
	int tid = 0;
	if (argc == 2) {
		tid = rz_num_math (core->num, argv[1]);
	}
	rz_core_task_join (&core->tasks, core->tasks.current_task, tid ? tid : -1);
	return RZ_CMD_STATUS_OK;
}